﻿using System;
using System.Text.RegularExpressions;
using System.Xml;

namespace Jerry.DroidBuilder.ThemeEditor
{
    public class LayoutLoader
    {
        public const string RESOURCE_PATTERN = "^@\\+?(\\w+)/([\\w_]+)$";
        public const string UNIT_PATTERN = "^([\\d+\\.]+)(dp|dip|ps)$";
        public const double SCREEN_DENSITY = 240f;

        public static LayoutInfo Load(string fileName)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(fileName);

            return Load(doc);
        }

        public static LayoutInfo LoadXml(string xml)
        {
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xml);

            return Load(doc);
        }

        private static LayoutInfo Load(XmlDocument doc)
        {
            var node = doc.SelectSingleNode("/*");
            var element = GetLayoutInfo(node);

            return element;
        }

        private static LayoutInfo GetLayoutInfo(XmlNode node)
        {
            var layoutType = node.Name;

            if (layoutType == "element")
            {
                try
                {
                    layoutType = node.Attributes["layout_type"].Value;
                }
                catch (Exception)
                {
                    layoutType = string.Empty;
                }

                if (string.IsNullOrEmpty(layoutType))
                {
                    layoutType = "FrameLayout";
                }
            }

            var info = new LayoutInfo(layoutType);

            if (null != node.Attributes)
            {
                foreach (XmlAttribute attr in node.Attributes)
                {
                    info.SetValue(attr.LocalName, ParseAttributeValue(attr.Value));
                }
            }

            if (null != node.ChildNodes)
            {
                foreach (XmlNode cnode in node.ChildNodes)
                {
                    info.Children.Add(GetLayoutInfo(cnode));
                }
            }

            return info;
        }

        private static string ParseAttributeValue(string attrValue)
        {
            if (string.IsNullOrEmpty(attrValue))
            {
                return attrValue;
            }

            var match = Regex.Match(attrValue, UNIT_PATTERN);

            if (match.Success)
            {
                var result = attrValue;

                switch (match.Groups[2].Value)
                {
                    case "dp":
                    case "dip":
                        // TODO: Currently, only support 240 density.
                        result = (SCREEN_DENSITY / 160f * double.Parse(match.Groups[1].Value) + 0.5f).ToString();
                        break;
                    case "ps":
                        // TODO: No user preference suppport.
                        result = (SCREEN_DENSITY / 160f * double.Parse(match.Groups[1].Value) + 0.5f).ToString();
                        break;
                    default:
                        break;
                }

                return result;
            }

            match = Regex.Match(attrValue, RESOURCE_PATTERN);

            if (match.Success)
            {
                var result = attrValue;
                var type = match.Groups[1].Value;
                var name = match.Groups[2].Value;

                switch (type)
                {
                    case "drawable":
                        //result = GetDrawable(name, attrValue);
                        break;
                    case "color":
                    case "string":
                    case "bool":
                    case "integer":
                        result = GetResourceValue(name, type, attrValue);
                        break;
                    case "style":
                        break;
                    case "array":
                        break;
                    default:
                        break;
                }

                return result;
            }

            return attrValue;
        }

        private static string GetResourceValue(string name, string resourceType, string defaultValue)
        {
            var result = defaultValue;
            var doc = new XmlDocument();

            doc.Load(string.Format(@"D:\Jerry\android\apktool\framework-res\res\values\{0}s.xml", resourceType));

            var node = doc.SelectSingleNode(string.Format("/resources/{0}[@name='{1}']", resourceType, name));

            if (null != node)
            {
                result = node.InnerText;
            }

            return result;
        }

        //private static string GetDrawable(string name, string defaultValue)
        //{
        //    var drawables = Directory.GetFiles(@"D:\Jerry\android\apktool\framework-res\res", string.Format("{0}.*", name), SearchOption.AllDirectories);

        //    if (drawables.Length <= 0)
        //    {
        //        return defaultValue;
        //    }

        //    return drawables[0];
        //}
    }
}
